#ifndef _CheckerTexture_H_
#define _CheckerTexture_H_

#pragma once
#include "Texture.h"
class CheckerTexture : public Texture {
private:
	shared_ptr<Material> black, white;

public:
	CheckerTexture(shared_ptr<Material> black, shared_ptr<Material> white, const Vector3 &scale = Vector3(1, 1, 1)) : black(black), white(white) {
		this->scale = scale;
	}
	CheckerTexture(const Vector3 &scale = Vector3(1, 1, 1)) : black(make_shared<ColorMaterial>(Colors::Black)), white(make_shared<ColorMaterial>(Colors::White)) {
		this->scale = scale;
	}
	~CheckerTexture() {}

	Color shade(const Scene *scene, const Ray &ray, const IntersectResult &intersect, const TraceState & traceState) const {
		bool whiteCheck;
		switch (mapping) {
		case Texture::UV:
			whiteCheck = isWhite(intersect.uv.x * scale.x + offset.x, intersect.uv.y * scale.y + offset.y, offset.z);
			break;
		case Texture::Position:
			whiteCheck = isWhite(intersect.position.x * scale.x + offset.x, intersect.position.y * scale.y + offset.y, intersect.position.z * scale.z + offset.z);
			break;
		default:
			return Colors::Black;
		}
		return whiteCheck ? black->shade(scene, ray, intersect, traceState) : white->shade(scene, ray, intersect, traceState);
	}

	bool isWhite(Double u, Double v, Double w) const {
		return abs(fastFloor(u + 1e-9) + fastFloor(v + 1e-9) + fastFloor(w + 1e-9)) % 2 < 1;
	}
};

#endif // _CheckerTexture_H_